From 321cf99bd2206e741a89b5ac350dfe3f182a00a3 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 29 Apr 2016 17:29:03 +0100
Subject: [PATCH] Revert "bcm2835: implement channel map API"

This reverts commit 5efba3f8c180c39609a8d40033ef92046ef0de75.
---
 sound/arm/bcm2835-ctl.c   | 299 ----------------------------------------------
 sound/arm/bcm2835-pcm.c   |  69 ++---------
 sound/arm/bcm2835-vchiq.c |  13 --
 sound/arm/bcm2835.h       |   4 -
 4 files changed, 7 insertions(+), 378 deletions(-)

--- a/sound/arm/bcm2835-ctl.c
+++ b/sound/arm/bcm2835-ctl.c
@@ -327,304 +327,6 @@ static struct snd_kcontrol_new snd_bcm28
 	},
 };
 
-struct cea_channel_speaker_allocation {
-	int ca_index;
-	int speakers[8];
-};
-
-#define FL	SNDRV_CHMAP_FL
-#define FR	SNDRV_CHMAP_FR
-#define RL	SNDRV_CHMAP_RL
-#define RR	SNDRV_CHMAP_RR
-#define LFE	SNDRV_CHMAP_LFE
-#define FC	SNDRV_CHMAP_FC
-#define RLC	SNDRV_CHMAP_RLC
-#define RRC	SNDRV_CHMAP_RRC
-#define RC	SNDRV_CHMAP_RC
-#define FLC	SNDRV_CHMAP_FLC
-#define FRC	SNDRV_CHMAP_FRC
-#define FLH	SNDRV_CHMAP_TFL
-#define FRH	SNDRV_CHMAP_TFR
-#define FLW	SNDRV_CHMAP_FLW
-#define FRW	SNDRV_CHMAP_FRW
-#define TC	SNDRV_CHMAP_TC
-#define FCH	SNDRV_CHMAP_TFC
-
-/*
- * CEA-861 channel maps
- *
- * Stolen from sound/pci/hda/patch_hdmi.c
- * (unlike the source, this uses SNDRV_* constants directly, as by the
- *  map_tables array in patch_hdmi.c)
- * Unknown entries use 0, which unfortunately is SNDRV_CHMAP_UNKNOWN instead
- * of SNDRV_CHMAP_NA.
- */
-static struct cea_channel_speaker_allocation channel_allocations[] = {
-/*			  channel:   7     6    5    4    3     2    1    0  */
-{ .ca_index = 0x00,  .speakers = {   0,    0,   0,   0,   0,    0,  FR,  FL } },
-				 /* 2.1 */
-{ .ca_index = 0x01,  .speakers = {   0,    0,   0,   0,   0,  LFE,  FR,  FL } },
-				 /* Dolby Surround */
-{ .ca_index = 0x02,  .speakers = {   0,    0,   0,   0,  FC,    0,  FR,  FL } },
-				 /* surround40 */
-{ .ca_index = 0x08,  .speakers = {   0,    0,  RR,  RL,   0,    0,  FR,  FL } },
-				 /* surround41 */
-{ .ca_index = 0x09,  .speakers = {   0,    0,  RR,  RL,   0,  LFE,  FR,  FL } },
-				 /* surround50 */
-{ .ca_index = 0x0a,  .speakers = {   0,    0,  RR,  RL,  FC,    0,  FR,  FL } },
-				 /* surround51 */
-{ .ca_index = 0x0b,  .speakers = {   0,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
-				 /* 6.1 */
-{ .ca_index = 0x0f,  .speakers = {   0,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-				 /* surround71 */
-{ .ca_index = 0x13,  .speakers = { RRC,  RLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-
-{ .ca_index = 0x03,  .speakers = {   0,    0,   0,   0,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x04,  .speakers = {   0,    0,   0,  RC,   0,    0,  FR,  FL } },
-{ .ca_index = 0x05,  .speakers = {   0,    0,   0,  RC,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x06,  .speakers = {   0,    0,   0,  RC,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x07,  .speakers = {   0,    0,   0,  RC,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x0c,  .speakers = {   0,   RC,  RR,  RL,   0,    0,  FR,  FL } },
-{ .ca_index = 0x0d,  .speakers = {   0,   RC,  RR,  RL,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x0e,  .speakers = {   0,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x10,  .speakers = { RRC,  RLC,  RR,  RL,   0,    0,  FR,  FL } },
-{ .ca_index = 0x11,  .speakers = { RRC,  RLC,  RR,  RL,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x12,  .speakers = { RRC,  RLC,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x14,  .speakers = { FRC,  FLC,   0,   0,   0,    0,  FR,  FL } },
-{ .ca_index = 0x15,  .speakers = { FRC,  FLC,   0,   0,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x16,  .speakers = { FRC,  FLC,   0,   0,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x17,  .speakers = { FRC,  FLC,   0,   0,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x18,  .speakers = { FRC,  FLC,   0,  RC,   0,    0,  FR,  FL } },
-{ .ca_index = 0x19,  .speakers = { FRC,  FLC,   0,  RC,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x1a,  .speakers = { FRC,  FLC,   0,  RC,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x1b,  .speakers = { FRC,  FLC,   0,  RC,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x1c,  .speakers = { FRC,  FLC,  RR,  RL,   0,    0,  FR,  FL } },
-{ .ca_index = 0x1d,  .speakers = { FRC,  FLC,  RR,  RL,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x1e,  .speakers = { FRC,  FLC,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x1f,  .speakers = { FRC,  FLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x20,  .speakers = {   0,  FCH,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x21,  .speakers = {   0,  FCH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x22,  .speakers = {  TC,    0,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x23,  .speakers = {  TC,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x24,  .speakers = { FRH,  FLH,  RR,  RL,   0,    0,  FR,  FL } },
-{ .ca_index = 0x25,  .speakers = { FRH,  FLH,  RR,  RL,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x26,  .speakers = { FRW,  FLW,  RR,  RL,   0,    0,  FR,  FL } },
-{ .ca_index = 0x27,  .speakers = { FRW,  FLW,  RR,  RL,   0,  LFE,  FR,  FL } },
-{ .ca_index = 0x28,  .speakers = {  TC,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x29,  .speakers = {  TC,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x2a,  .speakers = { FCH,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x2b,  .speakers = { FCH,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x2c,  .speakers = {  TC,  FCH,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x2d,  .speakers = {  TC,  FCH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x2e,  .speakers = { FRH,  FLH,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x2f,  .speakers = { FRH,  FLH,  RR,  RL,  FC,  LFE,  FR,  FL } },
-{ .ca_index = 0x30,  .speakers = { FRW,  FLW,  RR,  RL,  FC,    0,  FR,  FL } },
-{ .ca_index = 0x31,  .speakers = { FRW,  FLW,  RR,  RL,  FC,  LFE,  FR,  FL } },
-};
-
-static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
-				     unsigned int size, unsigned int __user *tlv)
-{
-	unsigned int __user *dst;
-	int count = 0;
-	int i;
-
-	if (size < 8)
-		return -ENOMEM;
-	if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
-		return -EFAULT;
-	size -= 8;
-	dst = tlv + 2;
-	for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
-		struct cea_channel_speaker_allocation *ch = &channel_allocations[i];
-		int num_chs = 0;
-		int chs_bytes;
-		int c;
-
-		for (c = 0; c < 8; c++) {
-			if (ch->speakers[c])
-				num_chs++;
-		}
-
-		chs_bytes = num_chs * 4;
-		if (size < 8)
-			return -ENOMEM;
-		if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) ||
-		    put_user(chs_bytes, dst + 1))
-			return -EFAULT;
-		dst += 2;
-		size -= 8;
-		count += 8;
-		if (size < chs_bytes)
-			return -ENOMEM;
-		size -= chs_bytes;
-		count += chs_bytes;
-		for (c = 0; c < 8; c++) {
-			int sp = ch->speakers[7 - c];
-			if (sp) {
-				if (put_user(sp, dst))
-					return -EFAULT;
-				dst++;
-			}
-		}
-	}
-	if (put_user(count, tlv + 1))
-		return -EFAULT;
-	return 0;
-}
-
-static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol,
-				     struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
-	bcm2835_chip_t *chip = info->private_data;
-	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx);
-	struct cea_channel_speaker_allocation *ch = NULL;
-	int res = 0;
-	int cur = 0;
-	int i;
-
-	if (mutex_lock_interruptible(&chip->audio_mutex))
-		return -EINTR;
-
-	if (!substream || !substream->runtime) {
-		res = -ENODEV;
-		goto unlock;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
-		if (channel_allocations[i].ca_index == chip->cea_chmap)
-			ch = &channel_allocations[i];
-	}
-
-	/* If no layout was set yet, return a dummy. Apparently the userspace
-	 * API will be confused if we don't. */
-	if (!ch)
-		ch = &channel_allocations[0];
-
-	for (i = 0; i < 8; i++) {
-		if (ch->speakers[7 - i])
-			ucontrol->value.integer.value[cur++] = ch->speakers[7 - i];
-	}
-	while (cur < 8)
-		ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA;
-
-unlock:
-	mutex_unlock(&chip->audio_mutex);
-	return res;
-}
-
-static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol,
-				     struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
-	bcm2835_chip_t *chip = info->private_data;
-	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx);
-	int i, prepared = 0, cea_chmap = -1;
-	int res = 0;
-	int remap[8];
-
-	if (mutex_lock_interruptible(&chip->audio_mutex))
-		return -EINTR;
-
-	if (!substream || !substream->runtime) {
-		res = -ENODEV;
-		goto unlock;
-	}
-
-	switch (substream->runtime->status->state) {
-	case SNDRV_PCM_STATE_OPEN:
-	case SNDRV_PCM_STATE_SETUP:
-		break;
-	case SNDRV_PCM_STATE_PREPARED:
-		prepared = 1;
-		break;
-	default:
-		res = -EBUSY;
-		goto unlock;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
-		struct cea_channel_speaker_allocation *ch = &channel_allocations[i];
-		int matches = 1;
-		int cur = 0;
-		int x;
-		memset(remap, 0, sizeof(remap));
-		for (x = 0; x < substream->runtime->channels; x++) {
-			int sp = ucontrol->value.integer.value[x];
-			while (cur < 8 && !ch->speakers[7 - cur])
-				cur++;
-			if (cur >= 8) {
-				/* user has more channels than ch */
-				matches = 0;
-				break;
-			}
-			if (ch->speakers[7 - cur] != sp) {
-				matches = 0;
-				break;
-			}
-			remap[x] = cur;
-			cur++;
-		}
-		for (x = cur; x < 8; x++) {
-			if (ch->speakers[7 - x]) {
-				/* ch has more channels than user */
-				matches = 0;
-				break;
-			}
-		}
-		if (matches) {
-			cea_chmap = ch->ca_index;
-			break;
-		}
-	}
-
-	if (cea_chmap < 0) {
-		res = -EINVAL;
-		goto unlock;
-	}
-
-	/* don't change the layout if another substream is active */
-	if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) {
-		res = -EBUSY; /* unsure whether this is a good error code */
-		goto unlock;
-	}
-
-	chip->cea_chmap = cea_chmap;
-	for (i = 0; i < 8; i++)
-		chip->map_channels[i] = remap[i];
-	if (prepared)
-		snd_bcm2835_pcm_prepare_again(substream);
-
-unlock:
-	mutex_unlock(&chip->audio_mutex);
-	return res;
-}
-
-static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip)
-{
-	struct snd_pcm_chmap *chmap;
-	struct snd_kcontrol *kctl;
-	int err, i;
-
-	err = snd_pcm_add_chmap_ctls(chip->pcm,
-				     SNDRV_PCM_STREAM_PLAYBACK,
-				     NULL, 8, 0, &chmap);
-	if (err < 0)
-		return err;
-	/* override handlers */
-	chmap->private_data = chip;
-	kctl = chmap->kctl;
-	for (i = 0; i < kctl->count; i++)
-		kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
-	kctl->get = snd_bcm2835_chmap_ctl_get;
-	kctl->put = snd_bcm2835_chmap_ctl_put;
-	kctl->tlv.c = snd_bcm2835_chmap_ctl_tlv;
-	return 0;
-}
-
 int snd_bcm2835_new_ctl(bcm2835_chip_t * chip)
 {
 	int err;
@@ -638,7 +340,6 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t *
 		if (err < 0)
 			return err;
 	}
-	snd_bcm2835_add_chmap_ctl(chip);
 	for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) {
 		err = snd_ctl_add(chip->card,
 				snd_ctl_new1(&snd_bcm2835_spdif[idx], chip));
--- a/sound/arm/bcm2835-pcm.c
+++ b/sound/arm/bcm2835-pcm.c
@@ -19,9 +19,6 @@
 
 #include "bcm2835.h"
 
-/* The hardware can not do much more num_channels*samplerate then this value */
-#define MAX_COMBINED_RATE 768000
-
 /* hardware definition */
 static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
 	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -110,31 +107,6 @@ static irqreturn_t bcm2835_playback_fifo
 	return IRQ_HANDLED;
 }
 
-
-static int rate_hw_constraint_rate(struct snd_pcm_hw_params *params,
-				   struct snd_pcm_hw_rule *rule)
-{
-	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	struct snd_interval rates = {
-		.min = 8000,
-		.max = min(192000u, MAX_COMBINED_RATE / max(channels->min, 1u)),
-	};
-	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-	return snd_interval_refine(rate, &rates);
-}
-
-static int rate_hw_constraint_channels(struct snd_pcm_hw_params *params,
-				       struct snd_pcm_hw_rule *rule)
-{
-	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-	struct snd_interval channels_interval = {
-		.min = 1,
-		.max = min(8u, MAX_COMBINED_RATE / max(rate->min, 1u)),
-	};
-	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	return snd_interval_refine(channels, &channels_interval);
-}
-
 /* open callback */
 static int snd_bcm2835_playback_open_generic(
 		struct snd_pcm_substream *substream, int spdif)
@@ -216,24 +188,8 @@ static int snd_bcm2835_playback_open_gen
 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
 				   16);
 
-	/* When playing PCM, pretend that we support the full range of channels
-	 * and sample rates. The GPU can't output it, but is able to resample
-	 * the data to a rate the hardware can handle it. This won't work with
-	 * compressed data; the resampler would just destroy it. */
-	if (spdif) {
-		err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-					  rate_hw_constraint_rate, NULL,
-					  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-		err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-					  rate_hw_constraint_channels, NULL,
-					  SNDRV_PCM_HW_PARAM_RATE, -1);
-	}
-
 	chip->alsa_stream[idx] = alsa_stream;
 
-	if (!chip->opened)
-		chip->cea_chmap = -1;
-
 	chip->opened |= (1 << idx);
 	alsa_stream->open = 1;
 	alsa_stream->draining = 1;
@@ -344,7 +300,8 @@ static int snd_bcm2835_pcm_hw_free(struc
 	return snd_pcm_lib_free_pages(substream);
 }
 
-int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream)
+/* prepare callback */
+static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
 {
 	bcm2835_chip_t *chip = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -352,6 +309,11 @@ int snd_bcm2835_pcm_prepare_again(struct
 	int channels;
 	int err;
 
+	audio_info(" .. IN\n");
+
+	if (mutex_lock_interruptible(&chip->audio_mutex))
+		return -EINTR;
+
 	/* notify the vchiq that it should enter spdif passthrough mode by
 	 * setting channels=0 (see
 	 * https://github.com/raspberrypi/linux/issues/528) */
@@ -367,23 +329,6 @@ int snd_bcm2835_pcm_prepare_again(struct
 		audio_error(" error setting hw params\n");
 	}
 
-	return err;
-}
-
-/* prepare callback */
-static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	bcm2835_chip_t *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
-
-	audio_info(" .. IN\n");
-
-	if (mutex_lock_interruptible(&chip->audio_mutex))
-		return -EINTR;
-
-	snd_bcm2835_pcm_prepare_again(substream);
-
 	bcm2835_audio_setup(alsa_stream);
 
 	/* in preparation of the stream, set the controls (volume level) of the stream */
--- a/sound/arm/bcm2835-vchiq.c
+++ b/sound/arm/bcm2835-vchiq.c
@@ -570,8 +570,6 @@ int bcm2835_audio_set_params(bcm2835_als
 	VC_AUDIO_MSG_T m;
 	AUDIO_INSTANCE_T *instance = alsa_stream->instance;
 	int32_t success;
-	uint32_t chmap_value;
-	int i;
 	int ret;
 	LOG_DBG(" .. IN\n");
 
@@ -595,21 +593,10 @@ int bcm2835_audio_set_params(bcm2835_als
 
 	instance->result = -1;
 
-	if (alsa_stream->chip->cea_chmap >= 0) {
-		chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24;
-	} else {
-		chmap_value = 0; /* force stereo */
-		for (i = 0; i < 8; i++)
-			alsa_stream->chip->map_channels[i] = i;
-	}
-	for (i = 0; i < 8; i++)
-		chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3);
-
 	m.type = VC_AUDIO_MSG_TYPE_CONFIG;
 	m.u.config.channels = channels;
 	m.u.config.samplerate = samplerate;
 	m.u.config.bps = bps;
-	m.u.config.channelmap = chmap_value;
 
 	/* Create the message available completion */
 	init_completion(&instance->msg_avail_comp);
--- a/sound/arm/bcm2835.h
+++ b/sound/arm/bcm2835.h
@@ -107,8 +107,6 @@ typedef struct bcm2835_chip {
 	int old_volume; /* stores the volume value whist muted */
 	int dest;
 	int mute;
-	int cea_chmap; /* currently requested Audio InfoFrame Data Byte 4 */
-	int map_channels[8];
 
 	unsigned int opened;
 	unsigned int spdif_status;
@@ -151,8 +149,6 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t *
 int snd_bcm2835_new_pcm(bcm2835_chip_t * chip);
 int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip);
 
-int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream);
-
 int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream);
 int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream);
 int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
